Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ShaderLab compilation error log and package build #2364

Merged
merged 114 commits into from
Oct 16, 2024

Conversation

Sway007
Copy link
Member

@Sway007 Sway007 commented Aug 27, 2024

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

change rollup config to produce 2 version ShaderLab package dist: Release and Editor.

// use release version
import { ShaderLab } from "@galacean/engine-shader-lab"

// use editor version

// umd
import { ShaderLab } from "@galacean/engine-shader-lab/dist/browser.editor";
// esmoudle
import { ShaderLab } from "@galacean/engine-shader-lab/dist/module.editor";
// commonjs
import { ShaderLab } from "@galacean/engine-shader-lab/dist/main.editor";

Improve the error log when compiation error of ShaderLab occur in Editor version.

6 errors occur!
ShaderLab.ts:167
CompilationError: Invalid engine constant: BlendFactor.SourceAlph22

|···                BlendState {
|···                  Enabled = true;
|···                  SourceColorBlendFactor = BlendFactor.SourceAlph22;
                                                           ^^^^^^^^^^^^
|···                  DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;
|···                  SourceAlphaBlendFactor = BlendFactor.One;

CompilationError: Invalid render queue Transparent22

|···                  WriteEnabled = false;
|···                }
|···                RenderQueueType = Transparent22;
                                      ^^^^^^^^^^^^^
|···              #else
|···                BlendState {

CompilationError: Invalid "BlendState" variable: blendState

|···              #endif
|···
|···              BlendState = blendState;
                               ^^^^^^^^^^
|···
|···              mat4 renderer_MVPMat;

CompilationError: undeclared identifier:attr2

|···                Varyings v;
|···              
|···                gl_Position = renderer_MVPMat * attr2.POSITION;
                                                    ^^^^^
|···                none();
|···                v.v_pos = gl_Position.xyz;

CompilationError: No overload function type found: none

|···              
|···                gl_Position = renderer_MVPMat * attr2.POSITION;
|···                none();
                    ^^^^^^
|···                v.v_pos = gl_Position.xyz;
|···                v.v_uv = attr.TEXCOORD_023;

CompilationError: referenced attribute not found: TEXCOORD_023

|···                none();
|···                v.v_pos = gl_Position.xyz;
|···                v.v_uv = attr.TEXCOORD_023;
                                  ^^^^^^^^^^^^
|···                return v;
|···              }

In Release version, ShaderLab will immediately terminate the compilation and throw when encountering an error.

related issue: #2248

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced error handling in shader processing, providing detailed error messages and context for debugging.
    • Introduced new error types for better categorization of issues, including PreprocessorError, CompilationError, and ScannerError.
    • Added a new verbose version of ShaderLab for improved diagnostic information during development.
    • Integrated a new method for scanning characters in the shader source.
    • Introduced a utility class for managing object pools and error handling in shader lab elements.
  • Chores

    • Streamlined the build process by removing unnecessary editor-related scripts from the configuration.
    • Standardized the build command across CI workflows for consistency.
    • Updated test cases to improve coverage and added new tests for handling compilation errors.
    • Removed unused imports and optimized variable declarations in test files.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a19e9ba and 4c47c15.

📒 Files selected for processing (1)
  • packages/shader-lab/src/common/BaseScanner.ts (7 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
packages/shader-lab/src/common/BaseScanner.ts

[warning] 120-120: packages/shader-lab/src/common/BaseScanner.ts#L120
Added line #L120 was not covered by tests


[warning] 126-126: packages/shader-lab/src/common/BaseScanner.ts#L126
Added line #L126 was not covered by tests


[warning] 139-139: packages/shader-lab/src/common/BaseScanner.ts#L139
Added line #L139 was not covered by tests


[warning] 145-146: packages/shader-lab/src/common/BaseScanner.ts#L145-L146
Added lines #L145 - L146 were not covered by tests

packages/shader-lab/src/common/BaseScanner.ts Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
packages/shader-lab/src/preprocessor/PpParser.ts (1)

134-135: Typo in error message and improved error reporting

The use of the reportError method here ensures consistent error handling, which is great. However, there's a small typo in the error message:

- `Shader slice "${includedPath}" not founded.`
+ `Shader slice "${includedPath}" not found.`

Please correct "not founded" to "not found".

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d83cb29 and a180d29.

📒 Files selected for processing (1)
  • packages/shader-lab/src/preprocessor/PpParser.ts (28 hunks)
🧰 Additional context used
🪛 Biome
packages/shader-lab/src/preprocessor/PpParser.ts

[error] 50-50: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 68-68: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (19)
packages/shader-lab/src/preprocessor/PpParser.ts (19)

Line range hint 25-40: Improved error handling and parsing context

The changes in this segment enhance the PpParser class by introducing new static properties for error tracking and parsing context. The use of conditional compilation for the _errors property is a good approach to provide detailed debugging information in verbose mode while keeping the release version optimized.

The switch from default export to named export is also a positive change, as it promotes better module management and explicit imports.

🧰 Tools
🪛 Biome

[error] 42-42: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 43-43: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


67-69: Improved parsing context and error handling

The changes to the parse method enhance error handling by allowing a null return to indicate parsing errors. Setting _scanningText and _scanningFile provides better context for error reporting throughout the parsing process.

Regarding the static analysis warning about using this in a static context: This is a valid use case in TypeScript for accessing static members within a class. If you prefer to make the code more explicit, you could replace this with PpParser, but it's not strictly necessary.

🧰 Tools
🪛 Biome

[error] 68-68: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


99-101: Enhanced error handling in verbose mode

This addition improves error handling in verbose mode by returning null when errors are encountered during parsing. This approach provides a clear signal to the caller that the parsing process failed, allowing for better error management and debugging in development environments.


110-114: Centralized error reporting

The new reportError method is a great addition that centralizes error reporting logic. This approach improves code maintainability and ensures consistent error object creation across the parser. It also makes it easier to modify error handling behavior in the future if needed.


Line range hint 140-148: Enhanced debugging information in verbose mode

The addition of BlockInfo creation and usage in verbose mode is a valuable improvement. This change provides more detailed context for debugging, allowing for better tracking of code blocks during the preprocessing stage. This extra information can be crucial for identifying and resolving complex issues in shader code.


Line range hint 168-178: Consistent enhancement of debugging information

This change follows the same pattern as previous additions, creating and using a BlockInfo object in verbose mode. This consistency in providing enhanced debugging information throughout the parser is commendable. It ensures that detailed context is available for all parsed blocks, which is crucial for effective debugging and error tracking in complex shader code.


Line range hint 203-213: Consistent approach to enhanced debugging

This change continues the pattern of adding detailed debugging information in verbose mode. The consistent use of BlockInfo objects across different parsing scenarios is praiseworthy. This approach ensures that comprehensive context is available throughout the entire parsing process, greatly aiding in debugging and error analysis for complex shader code.


221-232: Continued consistency in debugging enhancements

This change maintains the established pattern of adding detailed debugging information in verbose mode. The consistent approach to creating and using BlockInfo objects across various parsing scenarios is commendable. This uniformity in providing enhanced debugging context throughout the parser will significantly aid in troubleshooting and analyzing complex shader code issues.


Line range hint 235-246: Consistent implementation of debugging enhancements

This change follows the established pattern of adding detailed debugging information in verbose mode. The consistent creation and use of BlockInfo objects across different parsing scenarios demonstrate a thorough approach to enhancing the parser's debugging capabilities. This uniformity will greatly benefit developers when troubleshooting complex shader code issues.


309-310: Improved error reporting for relational expressions

This change enhances error reporting by using the centralized reportError method. The error message now provides more specific information about invalid operators in relational expressions. This improvement will make it easier for developers to identify and fix issues in shader code, particularly when dealing with complex expressions.


335-336: Consistent improvement in error reporting for shift expressions

This change continues the pattern of enhancing error reporting by using the centralized reportError method. The error message now provides specific information about invalid operators in shift expressions. This consistency in improving error reporting across different expression types will significantly aid developers in identifying and resolving issues in shader code.


359-360: Consistent enhancement of error reporting

This change maintains the pattern of improving error reporting by utilizing the centralized reportError method. The error message now provides specific information about invalid operators. This consistency in enhancing error reporting across various parts of the parser will greatly assist developers in quickly identifying and addressing issues in shader code.


381-382: Continued consistency in error reporting enhancements

This change follows the established pattern of improving error reporting by using the centralized reportError method. The error message provides specific information about invalid operators, maintaining consistency with previous improvements. This ongoing effort to enhance error reporting throughout the parser will significantly improve the debugging experience for developers working with shader code.


403-403: Consistent improvement in error reporting

This change maintains the pattern of enhancing error reporting by utilizing the centralized reportError method. The error message provides specific information about invalid operators, aligning with previous improvements. This consistency in improving error reporting across various parts of the parser will greatly aid developers in quickly identifying and resolving issues in shader code.


448-452: Enhanced error reporting for macro-related issues

These additions improve error reporting for macro-related issues by providing more specific error messages. The use of the reportError method for both invalid function macro usage and invalid const macro is consistent with the centralized error reporting approach. These enhancements will help developers quickly identify and resolve macro-related problems in shader code, improving the overall debugging experience.


461-466: Improved error reporting for invalid tokens

This addition enhances error reporting by providing a specific error message for invalid tokens encountered during parsing. The use of the reportError method is consistent with the centralized error reporting approach implemented throughout the parser. This improvement will help developers quickly identify and address syntax issues in shader code, further enhancing the debugging capabilities of the parser.


Line range hint 479-503: Enhanced debugging capabilities with source mapping

The addition of conditional compilation blocks for verbose mode in the method signatures and return types is a valuable improvement. Including the sourceMap property in verbose mode provides crucial debugging information, likely offering a mapping between the original and processed shader code. This enhancement will significantly aid developers in tracing issues back to their source in the original shader code, greatly improving the debugging experience for complex shader processing scenarios.


603-603: Consistent improvement in error reporting for macro redefinition

This change continues the pattern of enhancing error reporting by utilizing the centralized reportError method. The error message now provides specific information about redefined macros, particularly for those starting with "GL_". This consistency in improving error reporting across various parts of the parser, including macro handling, will greatly assist developers in identifying and resolving issues in shader code.


691-692: Comprehensive debugging enhancements for macro expansion

These changes consistently apply the pattern of adding detailed debugging information in verbose mode throughout the macro expansion process. The creation and use of BlockInfo objects, along with their inclusion in the expandSegments array, provide valuable context for debugging complex shader code.

This thorough approach to enhancing debugging capabilities across various stages of macro expansion will significantly aid developers in tracing and resolving issues related to macro processing in shader code. The consistency in implementing these improvements is commendable and will result in a more robust and developer-friendly preprocessing system.

Also applies to: 694-697, 699-701, 707-709, 712-714

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
packages/shader-lab/src/index.ts (1)

Line range hint 1-21: Consider updating documentation for new exports and modes.

The changes successfully implement the new Verbose mode and additional exports. To ensure clear understanding for users and maintainers:

  1. Update the package documentation to explain the difference between Release and Verbose modes.
  2. Clearly document the purpose and usage of the newly exported BaseScanner and GSError entities.
  3. If not already done, update any relevant README or API documentation to reflect these changes.

Would you like assistance in drafting documentation updates for these changes?

tests/src/shader-lab/Scanner.test.ts (2)

19-40: LGTM: Comprehensive test cases for various comment scenarios.

The additional test cases effectively cover multiple multi-line comments and comments without leading spaces, enhancing the overall test coverage.

Consider adding a test case for inline comments (e.g., // single line comment) to ensure complete coverage of all comment types. Here's a suggested implementation:

it("should handle inline comments", () => {
  const source = `// This is an inline comment
  nextToken`;
  const scanner = new BaseScanner(source);

  scanner.skipCommentsAndSpace();

  const token = scanner.scanToken();
  expect(token?.lexeme).to.equal("nextToken");
});

5-42: Well-structured test suite with good coverage.

The test suite is well-organized and provides good coverage for the skipCommentsAndSpace() method of the BaseScanner class.

Consider enhancing the test suite with the following:

  1. Edge cases: Test with empty input, very long comments, or nested comment-like structures.
  2. Error scenarios: Verify behavior with unclosed multi-line comments.
  3. Performance: Add a test with a large input to ensure efficient handling of extensive comments and whitespace.

Example for testing an unclosed multi-line comment:

it("should handle unclosed multi-line comments", () => {
  const source = `/* This comment is not closed
  nextToken`;
  const scanner = new BaseScanner(source);

  scanner.skipCommentsAndSpace();

  const token = scanner.scanToken();
  expect(token?.lexeme).to.equal("nextToken");
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a180d29 and 7c57e15.

📒 Files selected for processing (2)
  • packages/shader-lab/src/index.ts (1 hunks)
  • tests/src/shader-lab/Scanner.test.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
packages/shader-lab/src/index.ts (3)

3-5: LGTM: New internal export for BaseScanner added.

The addition of the BaseScanner export is correctly implemented. The @internal JSDoc tag appropriately indicates that this export is intended for internal use only.


16-17: LGTM: Mode initialization updated to "Verbose".

The change from "Editor" to "Verbose" mode under the _VERBOSE directive is consistent with the overall changes in this PR. This update aligns well with the improved error logging objectives.


7-9: Approve changes with a suggestion for directive consistency.

The changes align with the PR objectives, moving from _EDITOR to _VERBOSE directive and adding comprehensive error exports. However, ensure that all relevant parts of the codebase consistently use the _VERBOSE directive instead of _EDITOR.

To verify the consistent use of directives, run the following script:

✅ Verification successful

Adjust search commands to target TypeScript file extensions.

The previous rg commands failed because typescript is not a recognized file type. Please run the updated scripts below to verify the usage of _EDITOR and _VERBOSE directives within .ts and .tsx files.


Directive consistency verified.

All _EDITOR directives have been successfully replaced with _VERBOSE. No remaining _EDITOR directives found in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining _EDITOR directives that should be _VERBOSE

# Test: Search for _EDITOR directives. Expect: No results if all have been updated.
rg --type typescript '#if\s+_EDITOR'

# Test: Confirm _VERBOSE directives are used. Expect: Results showing _VERBOSE usage.
rg --type typescript '#if\s+_VERBOSE'

Length of output: 148


Script:

#!/bin/bash
# Description: Check for any remaining _EDITOR directives that should be _VERBOSE

# Test: Search for _EDITOR directives. Expect: No results if all have been updated.
rg '#if\s+_EDITOR' --glob '*.ts' --glob '*.tsx'

# Test: Confirm _VERBOSE directives are used. Expect: Results showing _VERBOSE usage.
rg '#if\s+_VERBOSE' --glob '*.ts' --glob '*.tsx'

Length of output: 10338

tests/src/shader-lab/Scanner.test.ts (1)

7-17: LGTM: Well-structured test case for skipping multi-line comments.

This test case effectively verifies that the skipCommentsAndSpace() method correctly handles multi-line comments and proceeds to the next token.

tests/src/shader-lab/Scanner.test.ts Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (5)
packages/shader-lab/src/preprocessor/MacroDefine.ts (1)

29-40: LGTM: Improved macro expansion with better error handling.

The new expandFunctionBody method is a good improvement over the old _expand method. It provides better error handling with GSError and uses the pre-computed _replaceRegex for efficient expansion.

Minor suggestion: Consider adding a comment explaining the expansion logic, especially the use of _replaceRegex, to improve code readability.

You could add a comment like this before the replace call:

// Replace each argument placeholder in the macro body with the corresponding provided argument
const expanded = this.body.lexeme.replace(this._replaceRegex, (_, m) => {
  // ...
});
packages/shader-lab/src/parser/ShaderTargetParser.ts (2)

118-127: Approve: Enhanced error handling with a suggestion.

The new error handling logic provides more detailed information about unexpected tokens, which is valuable for debugging. The use of ShaderLabUtils.createGSError ensures consistent error creation, and the conditional compilation keeps the verbose error handling out of production builds.

Consider adding a comment explaining why null is returned after pushing the error, to improve code clarity for future maintainers.


Line range hint 132-143: Approve: New debugging method with performance suggestion.

The _printStack method is a valuable addition for debugging in verbose mode. The use of conditional compilation ensures it doesn't impact production builds.

Consider using an array to collect the string parts and then joining them at the end, which could be more efficient for large stacks:

private _printStack(nextToken: BaseToken) {
  const parts: string[] = [];
  for (let i = 0; i < this._traceBackStack.length - 1; i++) {
    const state = <ENonTerminal>this._traceBackStack[i++];
    const token = this._traceBackStack[i];
    parts.push(`State${state} - ${(<BaseToken>token).lexeme ?? ParserUtils.toString(token as GrammarSymbol)};`);
  }
  parts.push(`State${this._traceBackStack[this._traceBackStack.length - 1]} --- ${nextToken.lexeme}`);
  Logger.info(parts.join(' '));
}

This approach could be more performant, especially for larger stack traces.

🧰 Tools
🪛 Biome

[error] 116-116: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/shader-lab/src/codeGen/GLESVisitor.ts (1)

53-61: LGTM: Improved type checking and error reporting

The changes enhance type checking for return types and attribute structs, aligning with the new error reporting mechanism. The condition for non-void return types is now more explicit, improving code clarity.

Consider updating the error message on line 61 to be consistent with the one on line 56:

- this._reportError(returnType.location, "main entry can only return struct.");
+ this._reportError(returnType.location, "main entry can only return struct or void.");

This change would make the error message consistent with the actual allowed return types.

Also applies to: 73-73

packages/shader-lab/src/contentParser/ShaderContentParser.ts (1)

Line range hint 26-524: Overall improvement with room for further refinement

The changes to the ShaderContentParser class significantly enhance its error handling capabilities and position tracking accuracy. The introduction of structured error objects and a centralized error collection mechanism improves debugging and error reporting.

However, there are still some inconsistencies in error handling across different methods. To further improve the code:

  1. Standardize the error handling approach across all methods.
  2. Consider implementing a unified error handling method to reduce code duplication.
  3. Add unit tests to cover the new error handling scenarios.

These refinements will make the code more maintainable and robust.

Would you like assistance in creating a unified error handling method or generating unit tests for the new error scenarios?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7c57e15 and 4c63401.

📒 Files selected for processing (5)
  • packages/shader-lab/src/codeGen/CodeGenVisitor.ts (3 hunks)
  • packages/shader-lab/src/codeGen/GLESVisitor.ts (5 hunks)
  • packages/shader-lab/src/contentParser/ShaderContentParser.ts (17 hunks)
  • packages/shader-lab/src/parser/ShaderTargetParser.ts (3 hunks)
  • packages/shader-lab/src/preprocessor/MacroDefine.ts (2 hunks)
🧰 Additional context used
🪛 Biome
packages/shader-lab/src/contentParser/ShaderContentParser.ts

[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 131-131: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 137-137: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 138-138: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 160-160: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 161-161: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (17)
packages/shader-lab/src/preprocessor/MacroDefine.ts (2)

3-4: LGTM: Updated imports align with new error handling approach.

The new imports for GSError, GSErrorName, and ShaderLabUtils are consistent with the improved error handling strategy mentioned in the PR objectives. The removal of ParserUtils import (as noted in the AI summary) also aligns with this change.


32-34: LGTM: Improved error handling for macro expansion.

The error handling in expandFunctionBody is well-implemented. It checks for argument count mismatch and throws a GSError with a clear message, error name, and location. This aligns with the PR objectives of improving error logging and provides valuable information for debugging.

packages/shader-lab/src/parser/ShaderTargetParser.ts (3)

11-17: Approve: Improved imports and conditional compilation.

The new imports and conditional compilation directives enhance the module's functionality and allow for efficient builds. The use of // #if _VERBOSE ensures that verbose error reporting is only included when necessary, potentially reducing the package size for non-verbose builds.


39-44: Approve: New errors getter with a reminder.

The addition of the errors getter is a good improvement for error reporting in verbose mode. The use of conditional compilation ensures it doesn't impact non-verbose builds.

However, there's still a potential typo in the property name sematicAnalyzer. Consider renaming it to semanticAnalyzer for clarity and consistency.


118-127: Approve: Removal of unreachable code.

The previously flagged unreachable code has been successfully removed, improving code clarity and addressing the issue raised in a past review comment. This change eliminates potential confusion and aligns with best practices for code maintenance.

packages/shader-lab/src/codeGen/GLESVisitor.ts (4)

9-9: LGTM: Import changes reflect updated dependencies

The addition of EKeyword import and removal of Logger import align with the changes in error handling approach. This modification suggests a shift towards using enum values and a different error reporting mechanism.


21-23: LGTM: Improved documentation

The addition of the @internal documentation comment enhances code clarity and follows best practices for documenting internal APIs.


32-34: LGTM: Enhanced error handling for verbose mode

The addition of the #if _VERBOSE block improves error handling capabilities in verbose mode, aligning with the PR objective of enhancing error logging for the Editor version.


Line range hint 1-160: Overall assessment: Changes align well with PR objectives

The modifications in this file successfully address the PR objectives by:

  1. Improving error logging for ShaderLab compilation errors in the Editor version.
  2. Implementing conditional compilation to support separate Editor and Release versions.
  3. Enhancing type checking and error reporting in the vertexMain method.

These changes contribute to a more robust and maintainable codebase, balancing the trade-offs between performance optimization and code clarity as discussed in the PR comments.

packages/shader-lab/src/codeGen/CodeGenVisitor.ts (5)

3-3: LGTM: Appropriate imports added for error handling

The new imports for ShaderPosition, ShaderRange, GSErrorName, and GSError are correctly added and properly wrapped in preprocessor directives. This allows for conditional imports based on the build configuration, which aligns with the PR objectives of supporting different compilation modes.

Also applies to: 10-11


19-21: LGTM: Error collection mechanism added

The addition of the errors array as a readonly property is a good approach for collecting errors in verbose mode. This aligns well with the PR objectives of improving error logging for the Editor version.


45-50: LGTM: Improved error handling for attribute and varying structures

The changes to visitPostfixExpression method enhance error handling for attribute and varying structure references. The implementation is consistent and aligns with the PR objectives by collecting errors only in verbose mode.

Also applies to: 53-58


193-199: LGTM: Centralized error reporting mechanism

The new _reportError method effectively centralizes error reporting logic. It handles different compilation modes appropriately, creating a GSError in verbose mode and throwing a standard Error otherwise. This implementation aligns well with the PR objectives of supporting different compilation modes and improving error handling.


Line range hint 1-199: LGTM: Comprehensive improvements to error handling and reporting

The changes to CodeGenVisitor.ts successfully implement improved error handling and reporting mechanisms. The use of preprocessor directives to support different compilation modes is consistent and aligns well with the PR objectives. The new errors property and _reportError method provide a robust framework for collecting and reporting errors in the Editor version, while maintaining efficient compilation for the Release version.

These changes enhance the overall quality of the ShaderLab compilation process and should significantly improve the debugging experience for developers using the Editor version.

packages/shader-lab/src/contentParser/ShaderContentParser.ts (3)

26-29: LGTM: Enhanced error handling mechanism

The addition of GSError and GSErrorName imports, along with the new static _errors array, introduces a more structured approach to error handling. This improvement will facilitate better error reporting and debugging in the shader compilation process.

Also applies to: 56-57


69-69: LGTM: Proper error state reset

The addition of this._errors.length = 0; in the reset method ensures that the error collection is cleared before each parsing operation. This prevents the accumulation of stale errors across multiple parse calls, maintaining the integrity of error reporting.

🧰 Tools
🪛 Biome

[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


117-117: LGTM: Improved position tracking

The replacement of scanner.curPosition with scanner.getCurPosition() across various methods is a positive change. Using a getter method ensures that the most up-to-date position is always retrieved, improving the accuracy of error reporting and code analysis.

Also applies to: 126-126, 133-133, 139-139, 157-157, 162-162, 354-354, 373-373, 382-382, 388-388, 396-396, 402-402, 420-420, 425-425, 464-464, 472-472, 478-478, 501-501, 519-519, 524-524

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
packages/shader-lab/src/preprocessor/MacroDefine.ts (3)

17-18: Approve new private properties with a minor suggestion.

The addition of _replaceRegex and _argsTextList as private properties is a good optimization. Initializing _replaceRegex in the constructor is more efficient than doing so in each method call.

Consider adding JSDoc comments to these properties to improve code documentation:

/** Regular expression for replacing macro arguments */
private _replaceRegex?: RegExp;

/** List of argument lexemes for quick access */
private readonly _argsTextList: string[];

32-41: Approve expandFunctionBody method with a suggestion for clarity.

The new expandFunctionBody method is a good improvement over the previous _expand method. It includes proper error checking and uses ShaderLabUtils.createGSError for standardized error creation. The regex replacement logic is concise and efficient.

To improve clarity, consider adding a comment explaining the regex replacement logic:

// Replace each argument placeholder with its corresponding value
const expanded = this.body.lexeme.replace(this._replaceRegex, (_, m) => {
  return args[this._argsTextList.indexOf(m)];
});

This will help future maintainers understand the purpose of the replacement at a glance.


Line range hint 1-41: Approve overall improvements with a suggestion for documentation.

The changes to the MacroDefine class significantly improve its functionality, efficiency, and error handling. These modifications align well with the PR objectives of enhancing error logging and package build processes.

To complete these improvements, consider updating the class-level JSDoc comment to reflect the new behavior and usage of the MacroDefine class. This will help maintain up-to-date documentation for developers using this class.

Example:

/**
 * Represents a macro definition in the shader preprocessor.
 * Handles both simple and function-like macros, providing methods for expansion and error handling.
 */
export class MacroDefine {
  // ... existing code ...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4c63401 and 87c719d.

📒 Files selected for processing (1)
  • packages/shader-lab/src/preprocessor/MacroDefine.ts (2 hunks)
🧰 Additional context used
🔇 Additional comments (1)
packages/shader-lab/src/preprocessor/MacroDefine.ts (1)

3-6: Verify the conditional compilation approach for imports.

The GSErrorName import is wrapped in a conditional compilation block for verbose mode. This approach might lead to different behavior between verbose and non-verbose modes. Consider the following:

  1. Ensure that GSErrorName is only used within conditionally compiled code blocks to prevent runtime errors in non-verbose mode.
  2. Verify that the error handling logic remains consistent across both modes.

To check for potential issues, run the following script:

This will help identify any usage of GSErrorName that might cause issues in non-verbose mode.

✅ Verification successful

Conditional Compilation for GSErrorName Verified Successfully.

No usage of GSErrorName found outside the conditional compilation blocks, ensuring consistent behavior between verbose and non-verbose modes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for GSErrorName usage outside of conditional compilation blocks

rg 'GSErrorName' --type typescript -g '!**/MacroDefine.ts' -C 5

Length of output: 208

packages/shader-lab/src/preprocessor/MacroDefine.ts Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
packages/shader-lab/src/preprocessor/MacroDefine.ts (2)

9-10: LGTM: New private properties optimize macro expansion.

The addition of _replaceRegex and _argsLexemes properties improves performance by avoiding recreation of these values on each macro expansion.

Consider adding JSDoc comments to explain the purpose of these properties, especially _argsLexemes, as it might not be immediately clear to other developers.


28-35: LGTM: Improved expandFunctionBody method with better error handling.

The new expandFunctionBody method is a good replacement for the previous _expand method. It includes proper error checking and uses the new error handling approach with ShaderLabUtils.createGSError.

Consider adding a comment explaining the regex replacement logic, as it might not be immediately clear to other developers how it maps the arguments to their replacements in the macro body.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 87c719d and eb515be.

📒 Files selected for processing (1)
  • packages/shader-lab/src/preprocessor/MacroDefine.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (2)
packages/shader-lab/src/preprocessor/MacroDefine.ts (2)

3-6: LGTM: New imports enhance error handling capabilities.

The addition of ShaderLabUtils and GSErrorName imports improves error handling. The conditional compilation for GSErrorName is a good practice for optimizing bundle size in non-verbose builds.


8-36: LGTM: Improved overall class structure.

The changes to the MacroDefine class have resulted in a more streamlined and efficient structure. The removal of the _expand method and the introduction of expandFunctionBody improve readability and maintainability.

The class now has a clearer separation of concerns, with the constructor handling initialization and expandFunctionBody focusing on the expansion logic.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (14)
packages/shader-lab/src/GSError.ts (1)

5-17: LGTM: Class declaration and constructor look good.

The GSError class is well-structured and follows TypeScript best practices. The use of public readonly for constructor parameters is a concise way to declare and initialize class properties.

Consider adding a default value for wrappingLineCount to make it easier to understand its purpose:

static wrappingLineCount = 2; // Number of context lines to include before and after the error
packages/shader-lab/src/codeGen/VisitorContext.ts (1)

63-75: LGTM: Improved error handling and type safety

The changes to referenceAttribute method significantly improve error handling and type safety:

  1. Using BaseToken instead of string provides more context for error reporting.
  2. The new error handling approach using ShaderLabUtils.createGSError is more consistent and informative.
  3. Early return for already referenced attributes is efficient.

Consider explicitly returning undefined when the attribute is found for consistency:

-    if (this._referencedAttributeList[ident.lexeme]) return;
+    if (this._referencedAttributeList[ident.lexeme]) return undefined;

This change would make the method's behavior more explicit and consistent with its return type.

packages/shader-lab/src/contentParser/ShaderContentParser.ts (7)

26-30: LGTM! Improved error handling setup

The new imports and the addition of the _errors array enhance the error management capabilities of the ShaderContentParser class. The conditional compilation for verbose mode is a good approach for debugging.

For consistency with other static properties, consider using PascalCase for the _errors array:

-  static _errors: GSError[] = [];
+  static Errors: GSError[] = [];

This change would align with the naming convention used for _engineType.

Also applies to: 57-57


187-196: Improve consistency in error handling

The new error handling using ShaderLabUtils.createGSError is good. However, consider throwing the error in non-verbose mode for consistency with other methods:

 // #if _VERBOSE
 this._errors.push(error);
 return;
+// #else
+throw error;
 // #endif

This change ensures that execution stops in both modes while still collecting the error in verbose mode.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 187-187: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L187
Added line #L187 was not covered by tests


[warning] 194-195: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L194-L195
Added lines #L194 - L195 were not covered by tests


244-254: Standardize error handling across methods

The error handling here follows a similar pattern but with slight inconsistencies. Consider standardizing the approach:

  1. Remove scanner.scanToCharacter(";"); as it might skip important content.
  2. Throw the error in non-verbose mode for consistent behavior.

Apply this pattern to all similar error handling blocks:

 // #if _VERBOSE
 this._errors.push(error);
-scanner.scanToCharacter(";");
 return;
+// #else
+throw error;
+// #endif

This standardization will improve code consistency and error handling reliability.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 244-244: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L244
Added line #L244 was not covered by tests


[warning] 251-253: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L251-L253
Added lines #L251 - L253 were not covered by tests


261-273: Align error handling across all parsing methods

The error handling in these methods follows the same pattern as the previous ones. Apply the same standardization approach to these blocks as well:

 // #if _VERBOSE
 this._errors.push(error);
-scanner.scanToCharacter(";");
 return;
+// #else
+throw error;
+// #endif

This change will ensure consistent error handling throughout the class.

Also applies to: 301-313, 332-341

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 262-262: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L262
Added line #L262 was not covered by tests


[warning] 269-271: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L269-L271
Added lines #L269 - L271 were not covered by tests


488-497: Align error handling for main entry reassignment

The error handling for main entry reassignment differs from the pattern used elsewhere. Consider aligning it with the standard approach:

 // #if _VERBOSE
-Logger.error(error.toString());
-throw error;
+this._errors.push(error);
+return;
+// #else
+throw error;
+// #endif

This change maintains consistency with the error handling pattern used in other parts of the class.


Line range hint 70-525: Enhance overall error handling consistency

While the new error handling approach is a significant improvement, there are still some inconsistencies across different methods. To further enhance the code:

  1. Standardize the error handling pattern across all methods, using the suggested approach in previous comments.
  2. Consider creating a private static method for error handling to reduce code duplication, e.g.:
private static _handleError(error: GSError) {
  // #if _VERBOSE
  this._errors.push(error);
  return;
  // #else
  throw error;
  // #endif
}
  1. Replace all error handling blocks with calls to this method.

This refactoring will significantly improve code consistency, reduce duplication, and make future maintenance easier.


Line range hint 1-525: Overall improvement in error handling with room for further enhancement

The changes to the ShaderContentParser class significantly improve its error handling capabilities:

  1. More detailed error information is now available.
  2. Multiple errors can be collected in verbose mode, aiding in debugging complex shaders.
  3. There's a clear separation between verbose and non-verbose error handling.

These improvements enhance the overall functionality and debuggability of the shader parsing process. However, to fully capitalize on these changes:

  1. Implement the suggested consistency improvements across all error handling blocks.
  2. Consider adding unit tests to cover the new error handling scenarios, especially for the verbose mode.
  3. Update the class documentation to reflect the new error handling behavior, particularly the difference between verbose and non-verbose modes.

These additional steps will ensure that the new error handling mechanism is robust, well-tested, and clearly documented for future maintenance.

packages/shader-lab/src/preprocessor/PpParser.ts (5)

1-14: Approve new imports and conditional compilation

The new imports and conditional compilation for _VERBOSE mode enhance error handling and debugging capabilities. This is a positive change that improves the module's functionality.

Consider the impact on bundle size due to the conditional compilation. Ensure that the _VERBOSE mode is only enabled in development environments to keep the production bundle lean.


Line range hint 25-40: Approve class structure improvements and new static properties

The changes from default to named export and the addition of new static properties enhance the class structure, error tracking, and parsing context. These improvements are beneficial for debugging and maintaining the code.

Consider replacing this with PpParser in static methods to improve code clarity and address the static analysis warning. For example:

- this._errors.length = 0;
+ PpParser._errors.length = 0;

- this._scanningText = scanner.source;
+ PpParser._scanningText = scanner.source;

- this._scanningFile = scanner.file;
+ PpParser._scanningFile = scanner.file;

This change makes the static nature of these properties more explicit.

🧰 Tools
🪛 Biome

[error] 42-42: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 43-43: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


Line range hint 67-101: Approve improved error handling and debugging capabilities

The changes to the parse method, including the null return type and new error handling logic for _VERBOSE mode, significantly improve error handling and debugging capabilities.

Consider the thread safety implications of using static properties for _scanningText and _scanningFile. If this class might be used in a multi-threaded environment, consider passing these values as method parameters instead of using static properties. This would improve thread safety and make the method's dependencies more explicit.

- static parse(scanner: PpScanner): string | null {
-   this._scanningText = scanner.source;
-   this._scanningFile = scanner.file;
+ static parse(scanner: PpScanner, scanningText: string, scanningFile: string): string | null {
+   const _scanningText = scanningText;
+   const _scanningFile = scanningFile;
  // ... rest of the method
}

This change would make the method more robust in different execution contexts.

🧰 Tools
🪛 Biome

[error] 64-64: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 68-68: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 71-71: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 71-71: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


134-135: Approve improved error handling for missing shader slices

The addition of error reporting for missing shader slices and the early return improve the robustness of the _parseInclude method.

Consider a minor improvement in the error message:

- this.reportError(id.location, `Shader slice "${includedPath}" not founded.`, scanner.source, scanner.file);
+ this.reportError(id.location, `Shader slice "${includedPath}" not found.`, scanner.source, scanner.file);

This corrects the grammatical error in the message ("not founded" to "not found").


309-310: Approve comprehensive error reporting improvements

The addition of multiple error reporting instances throughout the parsing logic significantly enhances the error handling capabilities of the parser. These changes provide more specific and contextual error messages, which will greatly aid in debugging and development.

For consistency and maintainability, consider creating constants for common error messages. This would make it easier to update error messages in the future and ensure consistency across the codebase. For example:

const ERROR_MESSAGES = {
  INVALID_OPERATOR_RELATION: "Invalid operator in relation expression.",
  INVALID_OPERATOR_SHIFT: "Invalid operator in shift expression.",
  INVALID_OPERATOR: "Invalid operator.",
  INVALID_FUNCTION_MACRO: "Invalid function macro usage",
  INVALID_CONST_MACRO: (macro: string) => `Invalid const macro: ${macro}`,
  // ... other error messages
};

// Usage
this.reportError(opPos, ERROR_MESSAGES.INVALID_OPERATOR_RELATION, scanner.source, scanner.file);

This approach would centralize error messages and make them easier to manage and update.

Also applies to: 335-336, 359-360, 381-382, 403-403, 448-448, 452-452

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between eb515be and fb3974e.

📒 Files selected for processing (9)
  • packages/shader-lab/src/GSError.ts (1 hunks)
  • packages/shader-lab/src/ShaderLabUtils.ts (1 hunks)
  • packages/shader-lab/src/codeGen/CodeGenVisitor.ts (3 hunks)
  • packages/shader-lab/src/codeGen/VisitorContext.ts (3 hunks)
  • packages/shader-lab/src/common/BaseScanner.ts (7 hunks)
  • packages/shader-lab/src/contentParser/ShaderContentParser.ts (17 hunks)
  • packages/shader-lab/src/parser/SemanticAnalyzer.ts (4 hunks)
  • packages/shader-lab/src/parser/ShaderTargetParser.ts (3 hunks)
  • packages/shader-lab/src/preprocessor/PpParser.ts (28 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/shader-lab/src/parser/ShaderTargetParser.ts
🧰 Additional context used
🪛 GitHub Check: codecov/patch
packages/shader-lab/src/GSError.ts

[warning] 23-23: packages/shader-lab/src/GSError.ts#L23
Added line #L23 was not covered by tests


[warning] 27-27: packages/shader-lab/src/GSError.ts#L27
Added line #L27 was not covered by tests

packages/shader-lab/src/codeGen/CodeGenVisitor.ts

[warning] 57-57: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L57
Added line #L57 was not covered by tests


[warning] 196-196: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L196
Added line #L196 was not covered by tests


[warning] 198-198: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L198
Added line #L198 was not covered by tests

packages/shader-lab/src/codeGen/VisitorContext.ts

[warning] 83-83: packages/shader-lab/src/codeGen/VisitorContext.ts#L83
Added line #L83 was not covered by tests

packages/shader-lab/src/common/BaseScanner.ts

[warning] 136-136: packages/shader-lab/src/common/BaseScanner.ts#L136
Added line #L136 was not covered by tests


[warning] 142-143: packages/shader-lab/src/common/BaseScanner.ts#L142-L143
Added lines #L142 - L143 were not covered by tests

packages/shader-lab/src/contentParser/ShaderContentParser.ts

[warning] 140-140: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L140
Added line #L140 was not covered by tests


[warning] 163-163: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L163
Added line #L163 was not covered by tests


[warning] 187-187: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L187
Added line #L187 was not covered by tests


[warning] 194-195: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L194-L195
Added lines #L194 - L195 were not covered by tests


[warning] 244-244: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L244
Added line #L244 was not covered by tests


[warning] 251-253: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L251-L253
Added lines #L251 - L253 were not covered by tests


[warning] 262-262: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L262
Added line #L262 was not covered by tests


[warning] 269-271: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L269-L271
Added lines #L269 - L271 were not covered by tests


[warning] 302-302: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L302
Added line #L302 was not covered by tests


[warning] 309-311: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L309-L311
Added lines #L309 - L311 were not covered by tests


[warning] 332-332: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L332
Added line #L332 was not covered by tests


[warning] 339-340: packages/shader-lab/src/contentParser/ShaderContentParser.ts#L339-L340
Added lines #L339 - L340 were not covered by tests

🪛 Biome
packages/shader-lab/src/ShaderLabUtils.ts

[error] 9-37: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 34-34: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

packages/shader-lab/src/contentParser/ShaderContentParser.ts

[error] 70-70: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 132-132: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 138-138: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 139-139: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 161-161: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 162-162: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

packages/shader-lab/src/parser/SemanticAnalyzer.ts

[error] 73-73: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

packages/shader-lab/src/preprocessor/PpParser.ts

[error] 50-50: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 68-68: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 69-69: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (32)
packages/shader-lab/src/ShaderLabUtils.ts (4)

1-7: LGTM: Imports are well-organized and appropriate.

The imports are correctly structured, including both external and local modules. The conditional import for GSError aligns well with its usage in the code.


12-22: Approve createObjectPool and simplify clearAllShaderLabObjectPool.

The createObjectPool method is well-implemented and serves its purpose effectively.

For clearAllShaderLabObjectPool, consider simplifying the loop using a for...of statement as suggested in a previous review:

static clearAllShaderLabObjectPool() {
  for (const pool of ShaderLabUtils._shaderLabObjectPoolSet) {
    pool.clear();
  }
}

This change enhances readability and aligns with modern TypeScript practices.


24-36: LGTM: createGSError method is well-implemented.

The createGSError method effectively uses conditional compilation to provide different behavior based on the _VERBOSE flag. This approach allows for more detailed error information in verbose mode while keeping the release version lean.

Note: The static analysis tool flagged line 34 as unreachable code. This is a false positive due to the conditional compilation. In the final compiled code, only one of the conditional branches will exist, making all the code reachable.

🧰 Tools
🪛 Biome

[error] 34-34: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)


9-10: 🛠️ Refactor suggestion

Consider refactoring to a module with functions.

The ShaderLabUtils class currently only contains static members, which goes against best practices and triggers a static analysis warning. To improve code organization and maintainability, consider refactoring this into a module with exported functions instead of a class, as suggested in a previous review.

Here's a suggested refactoring:

import { ClearableObjectPool, IPoolElement } from "@galacean/engine";

const shaderLabObjectPoolSet: ClearableObjectPool<IPoolElement>[] = [];

export function createObjectPool<T extends IPoolElement>(type: new () => T) {
  // Implementation here
}

export function clearAllShaderLabObjectPool() {
  // Implementation here
}

export function createGSError(
  message: string,
  errorName: GSErrorName,
  source: string,
  location: ShaderRange | ShaderPosition,
  file?: string
) {
  // Implementation here
}

This approach maintains the same functionality while addressing the static analysis warning and potentially improving code readability and maintainability.

🧰 Tools
🪛 Biome

[error] 9-37: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

packages/shader-lab/src/GSError.ts (2)

1-4: LGTM: Preprocessor directive and imports look good.

The use of the _VERBOSE preprocessor directive is a good practice for controlling the inclusion of this file in different build configurations. The imports are relevant to the functionality of the GSError class.


60-65: LGTM: GSErrorName enum is well-defined.

The GSErrorName enum provides a clear categorization of error types. Its placement outside the _VERBOSE block is appropriate, making it available in all builds, which is likely necessary for use elsewhere in the codebase.

packages/shader-lab/src/parser/SemanticAnalyzer.ts (5)

3-3: LGTM: Import changes align with improved error handling.

The changes to the imports, including the addition of GSErrorName, ShaderLab, and the conditional import of GSError, are consistent with the PR objectives to enhance error handling and support different compilation modes.

Also applies to: 8-11


26-27: LGTM: Error array type updated for consistency.

The change from SemanticError[] to GSError[] for the errors array, along with the conditional compilation directive, is consistent with the overall changes in error handling and the introduction of verbose mode.


45-47: LGTM: Reset method updated for verbose mode.

The addition of the conditional compilation block to clear the errors array in the reset method is consistent with the changes in error handling for verbose mode.


68-72: LGTM: Improved error handling for verbose mode.

The changes to the error method for verbose mode align well with the PR objectives. The use of GSError with additional context from ShaderLab._processingPassText enhances error reporting. Returning the error instead of throwing it allows for more flexible error handling in the calling code.


73-74: ⚠️ Potential issue

Remove unreachable code in non-verbose mode.

The non-verbose error handling branch contains unreachable code due to the conditional compilation directive. This issue was also identified in previous reviews.

To resolve this, remove the entire #else branch as it will never be executed in the compiled code. Apply this diff:

 // #if _VERBOSE
    const err = new GSError(GSErrorName.CompilationError, param.join(""), loc, ShaderLab._processingPassText);
    this.errors.push(err);
    return err;
- // #else
-    throw new Error(param.join(""));
 // #endif

This change will eliminate the unreachable code warning while maintaining the intended functionality for both verbose and non-verbose modes.

🧰 Tools
🪛 Biome

[error] 73-73: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

packages/shader-lab/src/codeGen/VisitorContext.ts (3)

5-11: LGTM: New imports enhance error handling and type safety

The new imports, including GSErrorName, BaseToken, ShaderLab, and ShaderLabUtils, are well-aligned with the changes in the referenceAttribute and referenceVarying methods. The conditional import of GSError for verbose mode is a good practice for managing different build configurations.


41-41: LGTM: Explicit private constructor

The addition of an explicit private constructor is a good practice. It reinforces the singleton pattern and makes the class's design intent clearer.


78-90: LGTM: Consistent improvements in error handling and type safety

The changes to referenceVarying method are consistent with those in referenceAttribute and offer similar benefits:

  1. Using BaseToken instead of string provides more context for error reporting.
  2. The new error handling approach using ShaderLabUtils.createGSError is more consistent and informative.
  3. Early return for already referenced varyings is efficient.

Consider explicitly returning undefined when the varying is found for consistency:

-    if (this._referencedVaryingList[ident.lexeme]) return;
+    if (this._referencedVaryingList[ident.lexeme]) return undefined;

This change would make the method's behavior more explicit and consistent with its return type.

The static analysis tool indicates that line 83 is not covered by tests. Let's verify the test coverage for this method:

Please review the test coverage and consider adding tests to cover the error case in the referenceVarying method if they are missing.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 83-83: packages/shader-lab/src/codeGen/VisitorContext.ts#L83
Added line #L83 was not covered by tests

packages/shader-lab/src/codeGen/CodeGenVisitor.ts (5)

3-3: LGTM: Imports updated for new error handling functionality

The new imports for ShaderPosition, ShaderRange, GSErrorName, and GSError are correctly added to support the enhanced error handling capabilities. The conditional import of GSError based on the _VERBOSE flag aligns well with the PR objectives of creating distinct versions for Release and Editor.

Also applies to: 10-13


20-22: LGTM: New errors property for improved error logging

The addition of the readonly errors property of type GSError[] enhances the class's ability to collect and store errors during code generation in verbose mode. This change aligns perfectly with the PR objectives of improving error logging for the Editor version.


46-51: LGTM: Enhanced error handling in visitPostfixExpression

The additions to the visitPostfixExpression method significantly improve error handling for attribute and varying structure references. The conditional error collection based on the _VERBOSE flag aligns well with the PR objectives of implementing different behaviors for Release and Editor versions. These changes contribute to the overall improvement in error logging as mentioned in the PR summary.

Also applies to: 54-59


194-200: LGTM: Centralized error reporting with _reportError method

The new _reportError method effectively centralizes error reporting logic, enhancing code maintainability. Its conditional behavior based on the _VERBOSE flag aligns perfectly with the PR objectives of implementing different error handling for Release and Editor versions. This implementation is consistent with the PR summary's description of error handling improvements.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 196-196: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L196
Added line #L196 was not covered by tests


[warning] 198-198: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L198
Added line #L198 was not covered by tests


57-57: Improve test coverage for conditional compilation paths

The static analysis tool indicates that some lines in conditional blocks (57, 196, 198) are not covered by tests. These lines are crucial for the different behavior in Release and Editor versions. To ensure robustness and prevent potential regressions, consider adding tests that cover both compilation modes.

To verify the current test coverage and identify gaps, you can run the following command:

This script will help identify existing tests and potential gaps in coverage for the different compilation modes.

Also applies to: 196-196, 198-198

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 57-57: packages/shader-lab/src/codeGen/CodeGenVisitor.ts#L57
Added line #L57 was not covered by tests

packages/shader-lab/src/contentParser/ShaderContentParser.ts (1)

70-70: LGTM! Proper error state reset

Clearing the _errors array in the reset method ensures that errors from previous parsing operations don't persist. This is a good practice for maintaining the clean state of the parser between operations.

🧰 Tools
🪛 Biome

[error] 70-70: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

packages/shader-lab/src/preprocessor/PpParser.ts (6)

110-114: Approve centralized error reporting method

The addition of the reportError method is a positive change. It centralizes error reporting, improving consistency across the class and leveraging the new GSError type for more structured error handling.

This change enhances the overall error handling strategy of the class.


Line range hint 140-148: Approve enhanced debugging capabilities

The addition of the BlockInfo object and its inclusion in expandSegments for _VERBOSE mode enhances the debugging capabilities of the parser. This change provides more context for error reporting and debugging, which is valuable for development and troubleshooting.

These changes will significantly aid in diagnosing issues during development.


461-466: Approve improved error reporting for invalid tokens

The addition of error reporting for invalid tokens in constant parsing is a valuable improvement. Including the problematic character in the error message provides crucial information for debugging.

This change will make it easier to identify and fix issues related to unexpected tokens in constant expressions.


Line range hint 479-503: Approve enhanced debugging with source mapping

The addition of the sourceMap property to the return type in _VERBOSE mode is a valuable enhancement. This change will provide better context for mapping preprocessed code to the original source, significantly aiding in debugging and development processes.

These changes demonstrate a thoughtful approach to improving the development experience while maintaining a lean production build.


Line range hint 553-565: Approve consistent implementation of debugging enhancements

The addition of conditional compilation for _VERBOSE mode and the creation of BlockInfo objects across various methods demonstrate a consistent approach to enhancing debugging capabilities. These changes provide more detailed context for debugging and error tracking throughout the parsing process.

This consistent implementation will greatly improve the ability to diagnose and fix issues during development, while keeping the production build optimized.

Also applies to: 578-587, 616-625, 633-644


691-715: Approve improvements in range creation and debugging capabilities

The use of ShaderLab.createRange for creating range objects improves consistency throughout the parser. The addition of conditional compilation for _VERBOSE mode and the creation of BlockInfo objects further enhance the debugging capabilities of the parser.

These changes contribute to a more robust and developer-friendly parsing system, with improved consistency and better debugging tools.

packages/shader-lab/src/common/BaseScanner.ts (6)

28-31: Conditional compilation of _line and _column

Wrapping _line and _column under the _VERBOSE flag ensures that line and column tracking is only included in verbose builds. This optimizes performance by avoiding unnecessary property initialization in production environments.


41-46: Refactored getCurPosition() with conditional parameters

The modification of getCurPosition() to include _line and _column only when _VERBOSE is defined is appropriate. This ensures that position information is accurate in verbose mode while maintaining efficiency in production builds.


85-93: Optimized _advance() method with conditional line and column updates

Including the line and column updates within the _VERBOSE conditional block in the _advance() method is a good approach. It prevents unnecessary computations in non-verbose builds, enhancing performance.


136-136: Add unit tests for the new error handling logic

The invocation of throwError in scanText introduces a new error handling path that is not currently covered by tests, as indicated by the code coverage report. Adding unit tests for this code path will ensure that errors are handled correctly and improve overall test coverage.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 136-136: packages/shader-lab/src/common/BaseScanner.ts#L136
Added line #L136 was not covered by tests


141-144: Introduction of throwError method enhances error handling

The new throwError method centralizes error creation and throwing logic, improving maintainability and consistency in error handling throughout the BaseScanner class.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 142-143: packages/shader-lab/src/common/BaseScanner.ts#L142-L143
Added lines #L142 - L143 were not covered by tests


51-57: ⚠️ Potential issue

Potential access of undefined properties _line and _column

The getters line and column access _line and _column, which are only defined under the _VERBOSE flag. When _VERBOSE is not defined, accessing these properties will result in undefined or cause errors.

Consider wrapping the getters with the _VERBOSE conditional compilation to prevent access when the properties are not defined:

+  // #if _VERBOSE
  get line() {
    return this._line;
  }

  get column() {
    return this._column;
  }
+  // #endif

Likely invalid or redundant comment.

Comment on lines 32 to 57
const lines = source.split("\n");

let diagnosticMessage = `${this.name}: ${message}\n\n`;
const lineSplit = "|···";

for (let i = start.line - GSError.wrappingLineCount, n = end.line + GSError.wrappingLineCount; i <= n; i++) {
diagnosticMessage += lineSplit + `${lines[i]}\n`;

if (i < start.line || i > end.line) continue;

let remarkStart = 0;
let remarkEnd = lines[i].length;
let paddingLength = lineSplit.length;
if (i === start.line) {
remarkStart = start.column;
paddingLength += start.column;
} else if (i === end.line) {
remarkEnd = end.column;
}
const remarkLength = Math.max(remarkEnd - remarkStart, 1);

diagnosticMessage += " ".repeat(paddingLength) + "^".repeat(remarkLength) + "\n";
}

return diagnosticMessage;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add bounds checking to prevent potential runtime errors.

The error message formatting logic is comprehensive and provides clear visual indication of the error location. However, there's a potential issue with accessing lines[i] without bounds checking, which could lead to runtime errors if i is out of bounds.

To prevent potential runtime errors, add bounds checking before accessing lines[i]:

 for (let i = start.line - GSError.wrappingLineCount, n = end.line + GSError.wrappingLineCount; i <= n; i++) {
+  if (i >= 0 && i < lines.length) {
     diagnosticMessage += lineSplit + `${lines[i]}\n`;
     
     // ... rest of the loop body ...
     
+  }
 }

This change ensures that we only access valid indices of the lines array, preventing potential runtime errors.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const lines = source.split("\n");
let diagnosticMessage = `${this.name}: ${message}\n\n`;
const lineSplit = "|···";
for (let i = start.line - GSError.wrappingLineCount, n = end.line + GSError.wrappingLineCount; i <= n; i++) {
diagnosticMessage += lineSplit + `${lines[i]}\n`;
if (i < start.line || i > end.line) continue;
let remarkStart = 0;
let remarkEnd = lines[i].length;
let paddingLength = lineSplit.length;
if (i === start.line) {
remarkStart = start.column;
paddingLength += start.column;
} else if (i === end.line) {
remarkEnd = end.column;
}
const remarkLength = Math.max(remarkEnd - remarkStart, 1);
diagnosticMessage += " ".repeat(paddingLength) + "^".repeat(remarkLength) + "\n";
}
return diagnosticMessage;
}
const lines = source.split("\n");
let diagnosticMessage = `${this.name}: ${message}\n\n`;
const lineSplit = "|···";
for (let i = start.line - GSError.wrappingLineCount, n = end.line + GSError.wrappingLineCount; i <= n; i++) {
if (i >= 0 && i < lines.length) {
diagnosticMessage += lineSplit + `${lines[i]}\n`;
if (i < start.line || i > end.line) continue;
let remarkStart = 0;
let remarkEnd = lines[i].length;
let paddingLength = lineSplit.length;
if (i === start.line) {
remarkStart = start.column;
paddingLength += start.column;
} else if (i === end.line) {
remarkEnd = end.column;
}
const remarkLength = Math.max(remarkEnd - remarkStart, 1);
diagnosticMessage += " ".repeat(paddingLength) + "^".repeat(remarkLength) + "\n";
}
}
return diagnosticMessage;
}

Comment on lines +19 to +31
override toString(): string {
let start: ShaderPosition, end: ShaderPosition;
const { message, location, source } = this;
if (!source) {
return message;
}

if (location instanceof ShaderPosition) {
start = end = location;
} else {
start = location.start;
end = location.end;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Test Coverage Missing for toString Method Scenarios

The toString method in GSError.ts lacks test coverage for the following scenarios:

  1. When source is falsy.
  2. When location is an instance of ShaderPosition.

Please add test cases to cover these scenarios to ensure consistent return types and comprehensive validation.

🔗 Analysis chain

Ensure consistent return type and improve test coverage.

The toString method handles different location types well. However, there are two points to consider:

  1. The early return when source is falsy might lead to inconsistent return types. Consider modifying it to always return a string:
if (!source) {
  return `${this.name}: ${message}`;
}
  1. Static analysis indicates that lines 23 and 27 are not covered by tests. Consider adding test cases to cover these scenarios:
    • When source is falsy
    • When location is an instance of ShaderPosition

To verify the test coverage, you can run the following command:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test coverage for GSError.ts

# Test: Look for test files related to GSError
fd -e test.ts -e spec.ts GSError

# Test: Check for test cases covering falsy source and ShaderPosition
rg -i 'test|describe|it.*gsError.*source.*falsy' $(fd -e test.ts -e spec.ts)
rg -i 'test|describe|it.*gsError.*ShaderPosition' $(fd -e test.ts -e spec.ts)

Length of output: 185777

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 23-23: packages/shader-lab/src/GSError.ts#L23
Added line #L23 was not covered by tests


[warning] 27-27: packages/shader-lab/src/GSError.ts#L27
Added line #L27 was not covered by tests

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
packages/shader-lab/src/common/BaseScanner.ts (2)

41-48: LGTM: Improved method naming and conditional compilation.

The renaming from curPosition to getCurPosition enhances method naming consistency. The conditional compilation for _VERBOSE mode aligns with the PR objective of producing distinct versions.

Consider using template literals for better readability:

return ShaderLab.createPosition(
  this._currentIndex,
  // #if _VERBOSE
  this._line,
  this._column
  // #endif
);

143-146: LGTM: New centralized error handling method.

The throwError method provides a centralized way to create and throw GSErrors, which should lead to more consistent error handling across the codebase.

However, the static analysis indicates that this method is not covered by tests. Consider adding unit tests to ensure proper functionality and maintain code coverage.

Would you like assistance in writing unit tests for the throwError method?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 144-145: packages/shader-lab/src/common/BaseScanner.ts#L144-L145
Added lines #L144 - L145 were not covered by tests

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between fb3974e and f0742cf.

📒 Files selected for processing (1)
  • packages/shader-lab/src/common/BaseScanner.ts (7 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
packages/shader-lab/src/common/BaseScanner.ts

[warning] 138-138: packages/shader-lab/src/common/BaseScanner.ts#L138
Added line #L138 was not covered by tests


[warning] 144-145: packages/shader-lab/src/common/BaseScanner.ts#L144-L145
Added lines #L144 - L145 were not covered by tests

🔇 Additional comments (6)
packages/shader-lab/src/common/BaseScanner.ts (6)

2-2: LGTM: New import for error handling.

The addition of GSErrorName import aligns with the PR objective of improving error logging for ShaderLab compilation errors.


51-59: LGTM: Added getters for line and column.

The new getters for line and column improve encapsulation and provide a clean interface for accessing these properties in verbose mode. The conditional compilation ensures these are only available when needed.


112-112: LGTM: Updated method call for consistency.

The change from curPosition to getCurPosition maintains consistency with the earlier method renaming.

Also applies to: 117-117, 119-119, 125-125


138-138: LGTM: Improved error handling in scanText.

The use of the new throwError method aligns with the PR objective of improving error handling. This change likely provides more detailed and consistent error reporting across the codebase.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 138-138: packages/shader-lab/src/common/BaseScanner.ts#L138
Added line #L138 was not covered by tests


176-176: LGTM: Updated method call for consistency.

The change from curPosition to getCurPosition maintains consistency with the earlier method renaming.

Also applies to: 179-179


87-95: LGTM: Simplified line and column tracking.

Removing the conditional compilation around line and column updates simplifies the code and ensures consistent tracking. However, consider the performance impact of always updating these values, especially for large files.

You might want to benchmark this change to ensure it doesn't significantly affect performance in non-verbose mode.

✅ Verification successful

Verified: Line and column tracking consistent.

The removal of conditional compilation around _line and _column in BaseScanner.ts ensures consistent tracking, aligning with their usage in Lexer.ts. No additional impacts detected based on the current codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the usage of _line and _column outside of _VERBOSE mode
rg --type typescript -g '!*.test.ts' '\b_line\b|\b_column\b' packages/shader-lab/src

Length of output: 121


Script:

#!/bin/bash
# Verify the usage of _line and _column outside of _VERBOSE mode
rg --type ts -g '!*.test.ts' '\b_line\b|\b_column\b' packages/shader-lab/src

Length of output: 895


Script:

#!/bin/bash
# Examine the context of _line and _column usage in Lexer.ts and other relevant files
ast-grep --lang typescript --pattern $'_line = $_' packages/shader-lab/src/lexer/Lexer.ts
ast-grep --lang typescript --pattern $'_column = $_' packages/shader-lab/src/lexer/Lexer.ts

Length of output: 183


Script:

#!/bin/bash
# Search for assignments to _line and _column in Lexer.ts and BaseScanner.ts
rg --type ts -g '!*.test.ts' 'this\._line\s*=' packages/shader-lab/src/lexer/Lexer.ts
rg --type ts -g '!*.test.ts' 'this\._column\s*=' packages/shader-lab/src/lexer/Lexer.ts
rg --type ts -g '!*.test.ts' 'this\._line\s*=' packages/shader-lab/src/common/BaseScanner.ts
rg --type ts -g '!*.test.ts' 'this\._column\s*=' packages/shader-lab/src/common/BaseScanner.ts

Length of output: 463

const lineSplit = "|···";

for (let i = start.line - GSError.wrappingLineCount, n = end.line + GSError.wrappingLineCount; i <= n; i++) {
diagnosticMessage += lineSplit + `${lines[i]}\n`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache lines[i]

@GuoLei1990 GuoLei1990 merged commit ab1ceb3 into galacean:dev/1.4 Oct 16, 2024
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request high priority High priority issue Rendering Rendering related functions shader Shader related functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants